;****************************************************************
;*  greypuzz.asm
;*              Maschinencode und Bild für PUZZLE-Demo
;*              ======================================
;*
;*  26.05.99    Bodo Wenzel     V1.0, Erstellung
;*  2008-04-01  Bodo Wenzel     V2.0, Umbau für Geräte mit
;*                              M1-Dekodierung, Übersetzung durch
;*                              AS von Alfred Arnold
;****************************************************************

        title   "GREYPUZZ V2.0"

        cpu     z80

;= Einsprünge ins BASIC-ROM =====================================

basic_vsync     equ     00220H
basic_ret_app1  equ     00292H
basic_ret_app2  equ     002A4H
basic_if_break  equ     00F46H

;= Platzierung bestimmen ========================================

        org     4009H

;= BASIC-Systemvariablen ========================================

        db      0               ;VERSN
        dw      0               ;E_PPC
        dw      dsp             ;D_FILE
        dw      dsp+1           ;DF_CC
        dw      var             ;VARS
        dw      0               ;DEST
        dw      var+1           ;E_LINE
        dw      last-1          ;CH_ADD
        dw      0               ;X_PTR
        dw      last            ;STKBOT
        dw      last            ;STKEND
        db      0               ;BERG
        dw      membot          ;MEM
        db      0               ;unbenutzt
        db      2               ;DF_SZ
        dw      0               ;S_TOP
        db      0FFH,0FFH,0FFH  ;LAST_K
        db      55              ;MARGIN
        dw      dsp             ;NXTLIN
        dw      0               ;OLDPPC
        db      0               ;FLAGX
        dw      0               ;STRLEN
        dw      00C8DH          ;T_ADDR
        dw      0               ;SEED
frames: dw      0FFFFH          ;FRAMES
        db      0,0             ;COORDS
        db      0BCH            ;PR_CC
        db      33,24           ;S_POSN
        db      01000000B       ;CDFLAG
        ds      33              ;Ausgabepuffer
membot: ds      30              ;Rechenpuffer
        ds      2               ;unbenutzt

;= Erste BASIC-Zeile, HRG-Code ==================================

line1:  db      0,1
        dw      line1end-$-2
        db      0EAH            ;REM

start:
        ld      hl,frames
        ld      a,(hl)
start2:
        cp      a,(hl)
        jr      z,start2        ;auf vertikalen Rücklauf warten

        ld      ix,hrg          ;ohne Bildsprung umschalten
        ret

hrg:
        inc     hl
        inc     b
        ld      b,2
        djnz    $               ;etwas Verzögerung

        ld      b,192           ;Anzahl Zeilen

        ld      hl,(pointer+0)
        ex      de,hl
        ld      hl,(pointer+2)
        ld      (pointer+0),hl
        ex      de,hl           ;Adressen tauschen
        ld      (pointer+2),hl  ;aktuelle Adresse holen

        ld      de,32           ;Offset von Zeile zu Zeile

        or      e               ;löscht das C-Flag (für hrg_dummy)
hrg_loop:
        ld      a,h
        ld      i,a
        ld      a,l
        call    hrg_dummy+8000H
        add     hl,de
        dec     b
        jp      nz,hrg_loop     ;noch nicht alle Zeilen?

        call    basic_ret_app1  ;BASIC in den unteren Zeilen

        call    basic_vsync     ;Tastaturabfrage usw.

        call    basic_if_break
        jr      nc,hrg_stop     ;BREAK?

        ld      ix,hrg
        jp      basic_ret_app2  ;BASIC in den oberen Zeilen

hrg_stop:
        ld      a,01EH
        ld      i,a             ;wieder Textmodus

        jp      basic_ret_app2  ;BASIC in den oberen Zeilen

hrg_dummy:
        ld      r,a             ;Videoausgabe starten
        db      0,0,0,0,0,0,0,0
        db      0,0,0,0,0,0,0,0
        db      0,0,0,0,0,0,0,0
        db      0,0,0,0,0,0,0,0 ;Dummycode
        ret     nc

pointer:
        dw      pic1,pic2       ;Zeiger auf die Grafiken

        db      076H            ;N/L
line1end:

;= Zweite BASIC-Zeile, Element verschieben ======================

line2:  db      0,2
        dw      line2end-$-2
        db      0EAH            ;REM

sh_par:
        db      2,2             ;Koordinaten der Lücke (x,y)
;----------------------------------------------------------------
;        Bildwechsel abwarten
vsync:
        ld      b,h
        ld      c,l             ;Register retten

        ld      hl,pointer+1
        ld      a,(hl)
vsync2:
        cp      a,(hl)
        jr      z,vsync2        ;auf Ende des Bildes warten

        ld      l,c
        ld      h,b             ;Register holen
        ret
;----------------------------------------------------------------
;        Stein nach oben (Lücke nach unten)
sh_up:
        ld      de,28*32+6+pic1+31*32
        ld      hl,(sh_par+0)
        add     hl,hl
        add     hl,hl
        add     hl,de           ;Zeiger auf erstes Byte

        ld      b,32            ;Anzahl Verschiebungen
su_loop:
        push    bc

        call    vsync           ;synchronisieren

        call    incr
        ld      de,pic2-pic1-32*32-3
        add     hl,de
        call    incr
        ld      de,pic1-pic2-33*32-3
        add     hl,de           ;eine Zeile herauf

        pop     bc
        djnz    su_loop         ;noch nicht alle?
        ret
;----------------------------------------------------------------
incr:
        ex      de,hl
        ld      hl,+32
        add     hl,de           ;Zieladresse

        ld      a,32            ;Anzahl
i_loop:
        ld      bc,4
        ldir                    ;eine Zeile kopieren

        ld      bc,+32-4
        add     hl,bc
        ex      de,hl
        add     hl,bc
        ex      de,hl           ;nächste Adresse

        dec     a
        jr      nz,i_loop       ;noch nicht alles?

        ld      bc,-32
        add     hl,bc
        dec     a
        ld      (hl),a
        inc     hl
        ld      (hl),a
        inc     hl
        ld      (hl),a
        inc     hl
        ld      (hl),a          ;eine Quellzeile löschen
        ret
;----------------------------------------------------------------
;        Stein nach unten (Lücke nach oben)
sh_down:
        ld      de,28*32+6+pic1+3
        ld      hl,(sh_par+0)
        add     hl,hl
        add     hl,hl
        add     hl,de           ;Zeiger auf erstes Byte

        ld      b,32            ;Anzahl Verschiebungen
sd_loop:
        push    bc

        call    vsync           ;synchronisieren

        call    decr
        ld      de,pic2-pic1+32*32+3
        add     hl,de
        call    decr
        ld      de,pic1-pic2+33*32+3
        add     hl,de           ;eine Zeile herab

        pop     bc
        djnz    sd_loop         ;noch nicht alle?
        ret
;----------------------------------------------------------------
decr:
        ex      de,hl
        ld      hl,-32
        add     hl,de           ;Zieladresse

        ld      a,32            ;Anzahl
d_loop:
        ld      bc,4
        lddr                    ;eine Zeile kopieren

        ld      bc,-32+4
        add     hl,bc
        ex      de,hl
        add     hl,bc
        ex      de,hl           ;nächste Adresse

        dec     a
        jr      nz,d_loop       ;noch nicht alles?

        ld      bc,+32
        add     hl,bc
        dec     a
        ld      (hl),a
        dec     hl
        ld      (hl),a
        dec     hl
        ld      (hl),a
        dec     hl
        ld      (hl),a          ;eine Quellzeile löschen
        ret
;----------------------------------------------------------------
;        Stein nach links (Lücke nach rechts)
sh_left:
        ld      de,28*32+6+pic1+31*32+7
        ld      hl,(sh_par+0)
        add     hl,hl
        add     hl,hl
        add     hl,de           ;Zeiger auf erstes Byte

        ld      b,32            ;Anzahl Verschiebungen
sl_loop:
        push    bc

        call    vsync           ;synchronisieren

        call    left
        ld      de,pic2-pic1+32*32
        add     hl,de
        call    left
        ld      de,pic1-pic2+32*32
        add     hl,de           ;eine Spalte nach links

        pop     bc
        djnz    sl_loop         ;noch nicht alle?
        ret
;----------------------------------------------------------------
left:
        ld      de,-32+7        ;Adressenoffset

        ld      b,32            ;Anzahl
l_loop:
        scf                     ;Quellspalte löschen
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)
        dec     hl
        rl      (hl)            ;eine Zeile schieben

        add     hl,de
        djnz    l_loop          ;noch nicht alles?
        ret
;----------------------------------------------------------------
;        Stein nach rechts (Lücke nach links)
sh_right:
        ld      de,28*32+6+pic1-4
        ld      hl,(sh_par+0)
        add     hl,hl
        add     hl,hl
        add     hl,de           ;Zeiger auf erstes Byte

        ld      b,32            ;Anzahl Verschiebungen
sr_loop:
        push    bc

        call    vsync           ;synchronisieren

        call    right
        ld      de,pic2-pic1-32*32
        add     hl,de
        call    right
        ld      de,pic1-pic2-32*32
        add     hl,de           ;eine Spalte nach rechts

        pop     bc
        djnz    sr_loop         ;noch nicht alle?
        ret
;----------------------------------------------------------------
right:
        ld      de,+32-7        ;Adressenoffset

        ld      b,32            ;Anzahl
r_loop:
        scf                     ;Quellspalte löschen
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)
        inc     hl
        rr      (hl)            ;eine Zeile schieben

        add     hl,de
        djnz    r_loop          ;noch nicht alles?
        ret
;----------------------------------------------------------------
        db      076H            ;N/L
line2end:

;= Dritte BASIC-Zeile, Graustufenbild ===========================

line3:  db      0,3
        dw      line3end-$-2
        db      0EAH            ;REM

        align   020H            ;weil R keinen Überlauf kann
pic1:
        include "image1.inc"
pic2:
        include "image2.inc"

        db      076H            ;N/L
line3end:

;= Restliche BASIC-Zeilen, zur Adressenausgabe ==================
;        Diese Zeilen werden vom Spiel überschrieben.

line10:
        db      0,10
        dw      line10end-$-2
        db      0F1H            ;LET
        db      02DH            ;H
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (start/128)&07FH
        db      (start*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line10end:

line20:
        db      0,20
        dw      line20end-$-2
        db      0F1H            ;LET
        db      038H            ;S
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (sh_par/128)&07FH
        db      (sh_par*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line20end:

line30:
        db      0,30
        dw      line30end-$-2
        db      0F1H            ;LET
        db      03AH            ;U
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (sh_up/128)&07FH
        db      (sh_up*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line30end:

line40:
        db      0,40
        dw      line40end-$-2
        db      0F1H            ;LET
        db      029H            ;D
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (sh_down/128)&07FH
        db      (sh_down*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line40end:

line50:
        db      0,50
        dw      line50end-$-2
        db      0F1H            ;LET
        db      031H            ;L
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (sh_left/128)&07FH
        db      (sh_left*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line50end:

line60:
        db      0,60
        dw      line60end-$-2
        db      0F1H            ;LET
        db      037H            ;R
        db      014H            ;=
        db      01CH            ;0
        db      07EH            ;Zahl
        db      08FH
        db      (sh_right/128)&07FH
        db      (sh_right*2)&0FFH
        db      000H
        db      000H
        db      076H            ;N/L
line60end:

line70:
        db      0,70
        dw      line70end-$-2
        db      0F5H            ;PRINT
        db      02DH            ;H
        db      01AH            ;,
        db      038H            ;S
        db      01AH            ;,
        db      03AH            ;U
        db      01AH            ;,
        db      029H            ;D
        db      01AH            ;,
        db      031H            ;L
        db      01AH            ;,
        db      037H            ;R
        db      076H            ;N/L
line70end:

line80:
        db      0,80
        dw      line80end-$-2
        db      0F9H            ;RAND
        db      0D4H            ;USR
        db      02DH            ;H
        db      076H            ;N/L
line80end:

line90:
        db      0,90
        dw      line90end-$-2
        db      0F9H            ;RAND
        db      0D4H            ;USR
        db      03AH            ;U
        db      076H            ;N/L
line90end:

line100:
        db      0,100
        dw      line100end-$-2
        db      0F9H            ;RAND
        db      0D4H            ;USR
        db      029H            ;D
        db      076H            ;N/L
line100end:

line110:
        db      0,110
        dw      line110end-$-2
        db      0F9H            ;RAND
        db      0D4H            ;USR
        db      031H            ;L
        db      076H            ;N/L
line110end:

line120:
        db      0,120
        dw      line120end-$-2
        db      0F9H            ;RAND
        db      0D4H            ;USR
        db      037H            ;R
        db      076H            ;N/L
line120end:

;- Leerer Bildschirm --------------------------------------------

dsp:    db      076H
        db      076H,076H,076H,076H,076H,076H,076H,076H
        db      076H,076H,076H,076H,076H,076H,076H,076H
        db      076H,076H,076H,076H,076H,076H,076H,076H

;- Keine BASIC-Variablen ----------------------------------------

var:    db      080H

;- Ende des abgespeicherten Bereichs ----------------------------

last:
        end
